package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"log"
	"time"
)

type Student struct {
	Name string
	Age int
}
func main() {
	//设置客户端连接
	clientOptions:=options.Client().ApplyURI("mongodb://localhost:27017")

	//连接到MongoDB
	client,err:=mongo.Connect(context.TODO(),clientOptions)
	if err!=nil{
		log.Fatal(err)
	}
	err=client.Ping(context.TODO(),nil)
	if err!=nil{
		log.Fatal(err)
	}
	fmt.Println("connect to mongoDB")
	// 指定获取要操作的数据集
	collection := client.Database("test").Collection("student")
	//插入
	//s1 := Student{"小红", 12}
	//s2 := Student{"小兰", 10}
	//s3 := Student{"小黄", 11}
	//insertresult,err:=collection.InsertOne(context.TODO(),s1)
	//if err != nil {
	//	log.Fatal(err)
	//}
	//fmt.Println(insertresult.InsertedID)
	//students:=[]interface{}{s2,s3} //必须interface
	//insertManyResult,err:=collection.InsertMany(context.TODO(),students)
	//if err != nil {
	//	log.Fatal(err)
	//}
	//fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)
	////更新
	filter:=bson.D{{"name","小兰"}}
	//update:=bson.D{
	//	{"$inc",bson.D{
	//		{"age",1},
	//	}},
	//}

	//updateResult,err:=collection.UpdateOne(context.TODO(),filter,update)
	//if err != nil {
	//	log.Fatal(err)
	//}
	//fmt.Printf("Matched %v documents and updated %v documents.\n", updateResult.MatchedCount, updateResult.ModifiedCount)

	//删除单个
	deleteResult,err:=collection.DeleteOne(context.TODO(),bson.D{{"name","小红"}})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult.DeletedCount)
	//删除所有
	deleteResult2, err := collection.DeleteMany(context.TODO(), bson.D{{}})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult2.DeletedCount)
	//查询单个
	var result Student
	err=collection.FindOne(context.TODO(),filter).Decode(&result)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Found a single document: %+v\n", result)

	//查询多个
	findopt:=options.Find()
	findopt.SetLimit(2)
	var results []Student
	cur,err:=collection.Find(context.TODO(),bson.D{{}},findopt)
	if err != nil {
		log.Fatal(err)
	}
	for cur.Next(context.TODO()){
		var elem Student
		err:=cur.Decode(&elem)
		if err != nil {
			log.Fatal(err)
		}
		results = append(results, elem)
	}
	if err := cur.Err(); err != nil {
		log.Fatal(err)
	}

	// 完成后关闭游标
	cur.Close(context.TODO())
	fmt.Printf("Found multiple documents (array of pointers): %#v\n", results)
	// 断开连接
	err = client.Disconnect(context.TODO())
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Connection to MongoDB closed.")
}


//连接池模式 在 mysql的md文件中有解释
func ConnectToDB(uri,name string ,timeout time.Duration,num uint64) (*mongo.Database,error) {
	ctx,cancel:=context.WithTimeout(context.Background(),timeout)
	defer cancel()
	o:=options.Client().ApplyURI(uri)
	o.SetMaxPoolSize(num)

	client,err:=mongo.Connect(ctx,o)
	if err !=nil{
		return nil ,err
	}
	return client.Database(name),nil
}